
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Browser;

namespace SignatureDraw
{


	public partial class SignatureDrawing : UserControl
	{

		
        private static double BEGIN_WIDTH = 8;			// Start up draw width
		private static double END_WIDTH  = 1;			// Minimum draw width
		private static Color LINE_COLOR  = Colors.Black;	// Line color
		private static double WIDTH_DEC = 0.1;			// Width decrement

		private double _currentWidth ;					// Store the current width
		private Boolean _mouseDown  = false;			// flag indicate if the mouse is down
		private Line _line;							// Shape object
		// Store the drawing data, with default drawing
		private String _drawData = "#81*52*83*52*115*54";
		
		// redraw properties
		private int _lineCounter = 0;					// The current # of lines
        private Point _lastPoint;
		private int _pointCounter = 0;					// The current # of points
		private String [] _allLines ;						// Store all the Lines
        private String[] _points;						// Store all the points
		private Boolean _replay  = false;				// Replay flag

        private static int FPS = 24;                // fps of the on enter frame event
        private DispatcherTimer _timer = new DispatcherTimer(); // on enter frame simulator
		private sigs sig;

        public SignatureDrawing(sigs sig)
        {
            InitializeComponent();
			
			this.sig = sig;
			this.Width= sigs.wh;
			this.Height= sigs.ht;
			// add the mouse event
            this.MouseLeftButtonDown +=new MouseButtonEventHandler(on_mouse_down);
            this.MouseLeftButtonUp +=new MouseButtonEventHandler(on_mouse_up);
            this.MouseMove +=new MouseEventHandler(on_mouse_move);
            KeyUp += new KeyEventHandler(on_key_down);
            this.KeyDown += new KeyEventHandler(SignatureDrawing_KeyDown);

            // start the enter frame event
            _timer = new DispatcherTimer();
            _timer.Interval = new TimeSpan(0, 0, 0, 0, 1000 / FPS);
            _timer.Tick += new EventHandler(_timer_Tick);
            _timer.Start();
			this._drawData = sigs.sig;
            redraw();
		}


		
		
        void SignatureDrawing_KeyDown(object sender, KeyEventArgs e)
        {
            throw new NotImplementedException();
        }
		
		public int getlinectr(){
			return _lineCounter;	
		}
		/////////////////////////////////////////////////////        
		// Handlers 
		/////////////////////////////////////////////////////	
		
		// replay function
		 void _timer_Tick(object sender, EventArgs e)
        {
			
            if(_replay){
                if (_lineCounter < _allLines.Length)
                {
					
                    // create a new Line 
                    if(_pointCounter == 0){
                        string pointData = _allLines[_lineCounter];
                        _points = pointData.Split(new Char[] { '*' });	
                        _currentWidth = BEGIN_WIDTH;
                    }
					
                    if(_pointCounter + 1< _points.Length){
                        if(_pointCounter < 2){
                            // move to the point first
                            _lastPoint  = new Point(Convert.ToDouble(_points[0]), Convert.ToDouble(_points[1]));
                        }else{
                                // create a new Line
                                _line = new Line();
                                _line.StrokeEndLineCap = PenLineCap.Round;
                                _line.StrokeStartLineCap = PenLineCap.Round;
                                _line.Stroke = new SolidColorBrush(LINE_COLOR);
                                _line.StrokeThickness = _currentWidth;
                                _line.X1 = _lastPoint.X;
                                _line.Y1 = _lastPoint.Y;
                                _line.X2 = Convert.ToDouble(_points[_pointCounter]);
                                _line.Y2 = Convert.ToDouble(_points[_pointCounter + 1]);
                                LayoutRootSD.Children.Add(_line);

                                _currentWidth = Math.Max(END_WIDTH, _currentWidth - WIDTH_DEC);
                                _lastPoint = new Point(Convert.ToDouble(_points[_pointCounter]), Convert.ToDouble(_points[_pointCounter + 1]));
                        }
                        _pointCounter += 2;
                    }else{
                        _pointCounter = 0;
                        _lineCounter ++;	
                    }
                }else{
                    // finish and reset
                    _replay = false;	
                    _line = null;
                }
				
            }
		}
		
		// detect key down, reply after 'r' is pressed
         private void on_key_down(object sender, KeyEventArgs e){
			
             if(e.Key == Key.R){
                 redraw();
             }
			
         }

		// mouse down event
		private void on_mouse_down(object sender, MouseButtonEventArgs e)
        {
            if (_replay) return;		// do nothing during drawing

            _mouseDown = true;
            _currentWidth = BEGIN_WIDTH;

            // save the last click point
			//Point transMousePos = element.TransformToVisual(canvas).Transform(mousePosition);
			//// Get the Mouse Position
    	        //Point pt = e.GetPosition(this);

           // Move the Popup
             //GeneralTransform tf = LayoutRootSD.TransformToVisual(this);
    		    //Point offset = tf.Transform(pt);

            // Move the Popup to the right Offsets
            //thePopup.HorizontalOffset = offset.X;
            //thePopup.VerticalOffset = offset.Y;

            // Show the Popup
             //thePopup.IsOpen = true;
			
			
			
			//_lastPoint = offset;
            _lastPoint = new Point(e.GetPosition(this).X, e.GetPosition(this).Y);

            // save the draw data
			//_drawData += "#" + offset.X + "*" + offset.Y;
            _drawData += "#" + e.GetPosition(this).X + "*" + e.GetPosition(this).Y;
			
		}
			
		private void on_mouse_up(object sender, MouseButtonEventArgs e)
        {
            if(_replay) return;	// do nothing during drawing
			
             //reset 
            _mouseDown = false;
            _lastPoint = new Point(0, 0);	
		}
		
		private void on_mouse_move(object sender, MouseEventArgs e)
        {
            if (_replay) return;	// do nothing during drawing


            PolyLineSegment polyLineSegment = new PolyLineSegment();

            PathFigure pathFigure = new PathFigure();
            pathFigure.Segments.Add(polyLineSegment);

            PathGeometry pathGeometry = new PathGeometry();
            pathGeometry.Figures.Add(pathFigure);

            Path path = new Path();
            path.Stroke = new SolidColorBrush(Colors.Black);
            path.StrokeThickness = 10;
            path.Data = pathGeometry;
            
            

            if (_mouseDown)
            {
                if (_lastPoint.X != 0 && _lastPoint.Y != 0)
                {
                    _lineCounter += 2;

                    // create a new Line
                    _line = new Line();
                    _line.StrokeEndLineCap = PenLineCap.Round;
                    _line.StrokeStartLineCap = PenLineCap.Round;
                    _line.Stroke = new SolidColorBrush(LINE_COLOR);
                    _line.StrokeThickness = _currentWidth;
                    _line.X1 = _lastPoint.X;
                    _line.Y1 = _lastPoint.Y;
                    _line.X2 = e.GetPosition(this).X;
                    _line.Y2 = e.GetPosition(this).Y;
                    LayoutRootSD.Children.Add(_line);

                    _currentWidth = Math.Max(END_WIDTH, _currentWidth - WIDTH_DEC);
                    _lastPoint = new Point(e.GetPosition(this).X, e.GetPosition(this).Y); 

                    // save the draw data
                    _drawData += ("*" + e.GetPosition(this).X + "*" + e.GetPosition(this).Y);
                }
            }
		}					
			
		/////////////////////////////////////////////////////        
		// Private Methods 
		/////////////////////////////////////////////////////	

        // clear the screen
        public void clearScreen()
        {
            while (LayoutRootSD.Children.Count > 0)
            {
                LayoutRootSD.Children.RemoveAt(0);
			
            }
			
        }

		
        public String getNewSig()
        {
            
			return this._drawData;
        }

		public String clearData()
        {
            _drawData = "";
			return _drawData;
        }
		
		
		public void setSig()
        {
            sigs.sig  = _drawData;
		
        }
		
		public void getSig()
        {
            _drawData = sigs.sig; 
        }
		
		public void set400()
        {
			
            this.Height = this.Height - 22; 
			
        }
		public void set500()
        {
            this.Height = this.Height + 22; 
        }
        /////////////////////////////////////////////////////        
        // Private Methods 
        /////////////////////////////////////////////////////	
		public void gobig(double v)
		{
    			// Increase ScaleX and ScaleY by 25%.
    			myScaleTransform.ScaleX = myScaleTransform.ScaleX * v;
    			myScaleTransform.ScaleY = myScaleTransform.ScaleY * v;
			sigs.ht = sigs.ht = sigs.ht * v;
			sigs.wh = sigs.wh = sigs.wh * v;
		}
		
		public void gosmall(double v)
		{
    			// Increase ScaleX and ScaleY by 25%.
    			myScaleTransform.ScaleX = myScaleTransform.ScaleX * v;
    			myScaleTransform.ScaleY = myScaleTransform.ScaleY * v;
			sigs.ht = sigs.ht = sigs.ht * v;
			sigs.wh = sigs.wh = sigs.wh * v;
		}
		
		public void redraw(){

			if(_replay) return;	// do nothing during drawing
			
			// clear the screen
			clearScreen();
			
			// reset properties
			_pointCounter = 0;
			_lineCounter = 0;
            _allLines = _drawData.Split(new Char[] { '#' });
			_replay = true;
		}
    }
}
